package mobi.intuitit.android.example.widget.scrollable;

import mobi.intuitit.android.x.launcher.side.HppIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.provider.Browser;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

/**
 * 
 * @author Bo
 * 
 */
public class ScrollableWidgetProvider extends AppWidgetProvider {

    static final String TAG = "Scrollable Widget Example";

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        Log.d(TAG, action);
        if (TextUtils.equals(action, HppIntent.ACTION.ACTION_READY)) {
            // Receive ready signal from Home++. If this had never been received, your widget is
            // most likely just running on a normal home application.
            onAppWidgetReady(context, intent);
        } else if (TextUtils.equals(action, HppIntent.ACTION.ACTION_FINISH)) {

        } else if (TextUtils.equals(action, HppIntent.ACTION.ACTION_ITEM_CLICK)) {
            // onItemClickListener
            onItemClick(context, intent);
        } else if (TextUtils.equals(action, HppIntent.ACTION.ACTION_VIEW_CLICK)) {
            // onClickListener
            onClick(context, intent);
        } else if (TextUtils.equals(action, HppIntent.ERROR.ERROR_SCROLL_CURSOR)) {
            // An error occured
            Log.e(TAG, intent.getStringExtra(HppIntent.EXTRA.EXTRA_ERROR_MESSAGE) + "");
        } else
            super.onReceive(context, intent);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);

        final int N = appWidgetIds.length;
        for (int i = 0; i < N; i++) {
            int appWidgetId = appWidgetIds[i];
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }

    /**
     * Receive ready intent from Home++, prepare scroll view resources
     * 
     * @param intent
     */
    private void onAppWidgetReady(Context context, Intent intent) {
        if (intent == null)
            return;

        final int appWidgetId = intent.getIntExtra(HppIntent.EXTRA.EXTRA_APPWIDGET_ID, -1);
        if (appWidgetId < 0) {
            Log.d(TAG, "Cannot get app widget id from ready intent");
            return;
        }

        // One intent, one list view
        Intent setupIntent = new Intent(HppIntent.ACTION.ACTION_SCROLL_WIDGET_START);

        setupIntent.putExtra(HppIntent.EXTRA.EXTRA_APPWIDGET_ID, appWidgetId);

        // Put the dummy view id in. Remoteviews do not support every kind of layout or view widget,
        // please keep this in mind.
        // http://d.android.com/guide/topics/appwidgets/index.html#CreatingLayout
        setupIntent.putExtra(HppIntent.EXTRA.EXTRA_VIEW_ID, R.id.dummy);

        // Put in a list view layout resource, which will be inflated on the Home++ side. In this
        // way, you have control over most attributes. In case this is not specified, Home++ will
        // create a default list view with default settings (cacheColorHint will be set to
        // #00000000).
        setupIntent.putExtra(HppIntent.EXTRA.Scroll.EXTRA_LISTVIEW_LAYOUT_ID,
                R.layout.listview);

        // Put in adapter infos: item layout, provider, mapping
        setupIntent.putExtra(HppIntent.EXTRA.Scroll.EXTRA_ITEM_LAYOUT_ID,
                R.layout.bookmark_item);
        putProvider(setupIntent);
        putMapping(setupIntent);

        // Home++ can set onClickListener for each child view of an item. Just put this extra in. By
        // default, an onItemClickListener will be set
        setupIntent.putExtra(HppIntent.EXTRA.Scroll.EXTRA_ITEM_CHILDREN_CLICKABLE, true);

        // Here is a quick way for handling the onItemClick: tell Home++ the uri (more precisely,
        // its column index to be queried) to start ACTION_VIEW intent with. When onItemClick is
        // fired, instead of sending a broadcast intent to your app widget, Home++ will send
        // ACTION_VIEW intent and set the string specified in this column as data uri.

        // However, if you have the EXTRA_ITEM_CHILDREN_CLICKABLE set to true, the onItemClick will
        // be be ignored.

        // replaceDummyIntent.putExtra(HppIntent.EXTRA.Scroll.EXTRA_ITEM_ACTION_VIEW_URI_INDEX,
        // Browser.HISTORY_PROJECTION_URL_INDEX);

        // Send it out
        context.sendBroadcast(setupIntent);
    }

    /**
     * On click of a child view in an item
     * 
     * @param context
     * @param intent
     */
    private void onClick(Context context, Intent intent) {
        int itemPosition = intent.getIntExtra(HppIntent.EXTRA.Scroll.EXTRA_ITEM_POS, -1);
        int viewId = intent.getIntExtra(HppIntent.EXTRA.EXTRA_VIEW_ID, -1);
        Toast.makeText(context, "click " + viewId + "@" + itemPosition, Toast.LENGTH_SHORT).show();
    }

    /**
     * On click of an item
     * 
     * @param context
     * @param intent
     */
    private void onItemClick(Context context, Intent intent) {
        int itemPosition = intent.getIntExtra(HppIntent.EXTRA.Scroll.EXTRA_ITEM_POS, -1);
        Toast.makeText(context, "click @" + itemPosition, Toast.LENGTH_SHORT).show();
    }

    /**
     * Put provider info into the intent
     * 
     * @param intent
     */
    private void putProvider(Intent intent) {
        if (intent == null)
            return;

        // Need to add the created date column to the query
        String[] columns = new String[Browser.HISTORY_PROJECTION.length + 1];
        System.arraycopy(Browser.HISTORY_PROJECTION, 0, columns, 0,
                Browser.HISTORY_PROJECTION.length);
        int createdColumnIndex = columns.length - 1;
        columns[createdColumnIndex] = Browser.BookmarkColumns.CREATED;

        // Prepare other arguments
        String whereClause = Browser.BookmarkColumns.BOOKMARK + " == 1";
        String orderBy = Browser.BookmarkColumns.CREATED + " DESC";
        String[] selectionArgs = null;

        // Put the data uri in as a string. Do not use setData, Home++ does not have a filter for
        // that
        intent.putExtra(HppIntent.EXTRA.Scroll.EXTRA_DATA_URI, Browser.BOOKMARKS_URI.toString());

        // Other arguments for managed query
        intent.putExtra(HppIntent.EXTRA.Scroll.EXTRA_PROJECTION, columns);
        intent.putExtra(HppIntent.EXTRA.Scroll.EXTRA_SELECTION, whereClause);
        intent.putExtra(HppIntent.EXTRA.Scroll.EXTRA_SELECTION_ARGUMENTS, selectionArgs);
        intent.putExtra(HppIntent.EXTRA.Scroll.EXTRA_SORT_ORDER, orderBy);

    }

    /**
     * Put mapping info into the intent
     * 
     * @param intent
     */
    private void putMapping(Intent intent) {
        if (intent == null)
            return;

        // Set mapping for 4 views in a bookmark item
        int[] cursorIndices = new int[4];
        int[] viewTypes = new int[4];
        int[] layoutIds = new int[4];
        int[] defaultResource = new int[4];
        boolean[] clickable = new boolean[4];

        // Favicon
        cursorIndices[0] = Browser.HISTORY_PROJECTION_FAVICON_INDEX;
        viewTypes[0] = HppIntent.EXTRA.Scroll.Types.IMAGEBLOB;
        layoutIds[0] = R.id.favicon;
        
        // default value has to be a resource reference
        defaultResource[0] = R.drawable.app_web_browser_sm;
        
        clickable[0] = true;

        // Title
        cursorIndices[1] = Browser.HISTORY_PROJECTION_TITLE_INDEX;
        viewTypes[1] = HppIntent.EXTRA.Scroll.Types.TEXTVIEW;
        layoutIds[1] = R.id.title;
        defaultResource[1] = R.string.no_title;
        clickable[1] = false;

        // Url
        cursorIndices[2] = Browser.HISTORY_PROJECTION_URL_INDEX;
        viewTypes[2] = HppIntent.EXTRA.Scroll.Types.TEXTVIEW;
        layoutIds[2] = R.id.url;
        defaultResource[2] = R.string.no_url;
        clickable[2] = false;

        // RelativeLayout
        cursorIndices[3] = -1; // No mapping to column is needed
        viewTypes[3] = HppIntent.EXTRA.Scroll.Types.VIEW;
        layoutIds[3] = R.id.bookmarkitem;
        clickable[3] = true;

        // Put these in
        intent.putExtra(HppIntent.EXTRA.Scroll.Mapping.EXTRA_VIEW_IDS, layoutIds);
        intent.putExtra(HppIntent.EXTRA.Scroll.Mapping.EXTRA_VIEW_TYPES, viewTypes);
        intent.putExtra(HppIntent.EXTRA.Scroll.Mapping.EXTRA_VIEW_CLICKABLE, clickable);
        intent.putExtra(HppIntent.EXTRA.Scroll.Mapping.EXTRA_DEFAULT_RESOURCES, defaultResource);
        intent.putExtra(HppIntent.EXTRA.Scroll.Mapping.EXTRA_CURSOR_INDICES, cursorIndices);
    }
}
